package apps;

import hypergraph.HyperEdge;
import hypergraph.HyperGraph;
import hypergraph.Node;

import java.awt.Dimension;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.JFrame;

import org.jgap.Chromosome;
import org.jgap.Configuration;
import org.jgap.DefaultFitnessEvaluator;
import org.jgap.FitnessFunction;
import org.jgap.Gene;
import org.jgap.Genotype;
import org.jgap.IChromosome;
import org.jgap.InvalidConfigurationException;
import org.jgap.Population;
import org.jgap.UnsupportedRepresentationException;
import org.jgap.event.EventManager;
import org.jgap.impl.BestChromosomesSelector;
import org.jgap.impl.ChromosomePool;
import org.jgap.impl.CrossoverOperator;
import org.jgap.impl.DefaultConfiguration;
import org.jgap.impl.GABreeder;
import org.jgap.impl.IntegerGene;
import org.jgap.impl.MutationOperator;
import org.jgap.impl.StockRandomGenerator;
import org.jgap.xml.GeneCreationException;
import org.jgap.xml.ImproperXMLException;
import org.jgap.xml.XMLManager;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.FRLayout2;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import evolution.CodonGene;
import evolution.GraphMapper;
import evolution.GraphMetricFitnessFunction;


public class GraphEvolver extends GraphViewApp{
	private static final int MAX_ALLOWED_EVOLUTIONS = 50000;

	Genotype population;

	
	public GraphEvolver(){
		super();
	}
	
	public void initEvolution() throws InvalidConfigurationException, IOException, SAXException, ImproperXMLException, GeneCreationException{
		Configuration conf = new Configuration();
		conf.setBreeder(new GABreeder());
		conf.setRandomGenerator(new StockRandomGenerator());
		conf.setEventManager(new EventManager());
		BestChromosomesSelector bestChromsSelector = new BestChromosomesSelector(conf, 0.90d);
		bestChromsSelector.setDoubletteChromosomesAllowed(true);
		conf.addNaturalSelector(bestChromsSelector, false);
		conf.setMinimumPopSizePercent(0);
	      //
		conf.setSelectFromPrevGen(1.0d);
		conf.setKeepPopulationSizeConstant(true);
		conf.setFitnessEvaluator(new DefaultFitnessEvaluator());
		conf.setChromosomePool(new ChromosomePool());
		conf.addGeneticOperator(new CrossoverOperator(conf, 0.35d));
		conf.addGeneticOperator(new MutationOperator(conf, 5));
		if(conf == null){
			System.out.println("no config");
		}

	    conf.setPreservFittestIndividual(true);
	    //conf.addGeneticOperator(a_operatorToAdd)

	    FitnessFunction myFunc =
	        new GraphMetricFitnessFunction();
	    conf.setFitnessFunction(myFunc);

	    if(conf == null){
			System.out.println("no config");
		}
	    // --------------------------------------------------------------
	    Gene[] sampleGenes = new Gene[2];
	    if(conf == null){
			System.out.println("no config");
		}
	    sampleGenes[0] = new CodonGene(conf, 4, 150, 1);
	    sampleGenes[1] = new CodonGene(conf, 4, 100, 1);
	    
	    IChromosome sampleChromosome = new Chromosome(conf, sampleGenes);
	    conf.setSampleChromosome(sampleChromosome);

	    conf.setPopulationSize(25);

	    // Create random initial population of Chromosomes.
	    // Here we try to read in a previous run via XMLManager.readFile(..)
	    // for demonstration purpose only!
	    // -----------------------------------------------------------------

	    try {
	      Document doc = XMLManager.readFile(new File("JGAPExample32.xml"));
	      population = XMLManager.getGenotypeFromDocument(conf, doc);
	    }
	    catch (UnsupportedRepresentationException uex) {
	      // JGAP codebase might have changed between two consecutive runs.
	      // --------------------------------------------------------------
	      population = Genotype.randomInitialGenotype(conf);
	    }
	    catch (FileNotFoundException fex) {
	      population = Genotype.randomInitialGenotype(conf);
	    }
	    // Now we initialize the population randomly, anyway (as an example only)!
	    // If you want to load previous results from file, remove the next line!
	    // -----------------------------------------------------------------------
	    population = Genotype.randomInitialGenotype(conf);
	    // Evolve the population. Since we don't know what the best answer
	    // is going to be, we just evolve the max number of times.
	    // ---------------------------------------------------------------

	}
	
	public void evolveGraph(){
	    long startTime = System.currentTimeMillis();
	    System.out.println("Evolving generation: ");
	    for (int i = 0; i < MAX_ALLOWED_EVOLUTIONS; i++) {

	      population.evolve();
	      System.out.println(i+" " + population.getFittestChromosome().getFitnessValue());
	      if(i % 10 == 0){
	    	  setGraph(new GraphMapper().map(population.getFittestChromosome()));
	      }
	    }
	    long endTime = System.currentTimeMillis();
	    System.out.println("Total evolution time: " + ( endTime - startTime)
	                       + " ms");
	    
	    
	    //setGraph(new GraphMapper().map(population.getFittestChromosome()));
	    
	}
	
	
	
	public static void main(String[] args){
		GraphEvolver ge = new GraphEvolver();
		try {
			ge.initEvolution();
			ge.evolveGraph();
		} catch (InvalidConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ImproperXMLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (GeneCreationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	@Override
	public void setLayout() {
		// TODO Auto-generated method stub
		
	}

}
